﻿using System.Net;
using System.Threading.Tasks;
using Letter.IO.Binary;
using Letter.IO.Transports;
using Letter.Net.Tcp;

namespace Telex;

sealed class TcpServer : ANetwork
{
    public TcpServer(SslServerConfig sslServerConfig, string secretkey, RpcHost host)
    {
        this.host = host;
        this.secretkey = secretkey;
        this.sslServerConfig = sslServerConfig;
        
        this.server = TcpProvider.Server();
        this.server.ConfigureConnection(() =>
        {
            return this.OnConfigureConnection(null);
        });
        this.server.Build();
    }

    private RpcHost host;
    private ITcpServer server;
    
    private string secretkey;
    private SslServerConfig sslServerConfig;

    public EndPoint BindEndPoint
    {
        get { return this.server.BindEndPoint; }
    }

    public ValueTask BindAsync(IPEndPoint point)
    {
        return new ValueTask(this.server.BindAsync(point));
    }
    
    protected override AConnection OnConfigureConnection(object token)
    {
        var config = new ConnectionFixedConfig()
        {
            host = this.host,
            order = BinaryOrder.BigEndian,
            secretkey = this.secretkey,
            onConnect = this.OnConnect,
            onDisconnect = this.OnDisconnect
        };
        
        RpcServerConnection connection;
        if (sslServerConfig == null)
        {
            connection = new RpcServerConnection(ref config);
        }
        else
        {
            connection = new RpcServerConnection(
                ref config,
                sslServerConfig.sslServerOptions,
                sslServerConfig.sslServerStreamFactory
                );
        }

        return connection;
    }

    public override ValueTask StopAsync()
    {
        return new ValueTask(this.server.StopAsync());
    }
}

